package download

import (
	"bytes"
	"context"
	"fmt"
	"github.com/asticode/go-astisub"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/text/gstr"
	"os/exec"
)

var YtDlp = ytDlp{
	executePath: "A:\\program\\bin\\network\\yt-dlp.exe",
	outputPath:  "A:\\",
}

type ytDlp struct {
	executePath string // 可执行程序路径
	outputPath  string // 输出路径

	arguments []string
	proxy     string // 代理
}

type SrtContent struct {
	Index int    `json:"index"`
	Start int64  `json:"start"`
	End   int64  `json:"end"`
	Text  string `json:"text"`
}

func (r *ytDlp) Proxy(proxy string) *ytDlp { // 代理
	r.proxy = proxy

	return r
}

func (r *ytDlp) Execute(ctx context.Context, params []string) string {
	params = append(params, "--proxy", r.proxy)
	cmd := exec.Command(r.executePath, params...)

	var stdoutBuffer, stderrBuffer bytes.Buffer
	cmd.Stdout = &stdoutBuffer
	cmd.Stderr = &stderrBuffer

	err := cmd.Run()
	if err != nil {
		glog.Warning(ctx, "ytDlp Execute error, error: %s, err: %+v", stderrBuffer.String(), err)
	}

	return stdoutBuffer.String()
}

func (r *ytDlp) Download(ctx context.Context, url, language string) (string, []byte) {
	var (
		title  string
		uniqid string
	)

	result := r.Proxy("http://localhost:7890").
		Execute(ctx, []string{
			"--skip-download", // 不下载
			"--get-filename",  // 获取文件名
			"-o", fmt.Sprintf("%%(title)s%s%%(id)s", "_&"),
			url,
		})
	fmt.Println(result)

	var fileInfos = gstr.Split(gstr.Trim(result, "\n"), "_&")
	if len(fileInfos) == 2 {
		title = fileInfos[0]
		uniqid = fileInfos[1]
	}
	fmt.Println(title)

	result2 := r.Proxy("http://localhost:7890").
		Execute(ctx, []string{
			"--skip-download",       // 不下载
			"--write-auto-subs",     //
			"--sub-langs", language, // 语言
			"--convert-subs", "srt", // 转换为 srt
			"-o", fmt.Sprintf(r.outputPath, uniqid), // 输出
			url,
		})

	for _, line := range gstr.Split(result2, "\n") {
		if gstr.Contains(line, "Downloading subtitles") {
			var downloadInfos = gstr.Split(gstr.TrimLeft(line, "[info]"), ":")
			if len(downloadInfos) == 3 {
				language = gstr.Trim(downloadInfos[2], "")
				// srtPath = fmt.Sprintf("%s.srt", language)
			}
		}
	}

	return r.FormatSrt(ctx, fmt.Sprintf(r.outputPath, uniqid, language, ".srt"))
}

func (r *ytDlp) FormatSrt(ctx context.Context, path string) (string, []byte) {
	result, err := astisub.OpenFile(path)
	if err != nil {
		glog.Warning(ctx, "ytDlp FormatSrt error, error: %+v", err)
	}

	var (
		contentText string
		subtitles   []*SrtContent
	)

	for _, item := range result.Items {
		var subtitle = &SrtContent{
			Index: item.Index,
			Start: item.StartAt.Milliseconds(),
			End:   item.EndAt.Milliseconds(),
		}

		for _, line := range item.Lines {
			for _, inline := range line.Items {
				subtitle.Text += inline.Text + "\n"
				contentText += inline.Text + "\n"
			}
		}

		subtitles = append(subtitles, subtitle)
	}

	contentSrt, err := gjson.Encode(subtitles)
	if err != nil {
		glog.Warningf(ctx, "ytDlp FormatSrt error, err: %+v", err)
	}

	return contentText, contentSrt
}
